home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / bss / pup.arc / EDIT.C < prev    next >
C/C++ Source or Header  |  1987-12-11  |  6KB  |  201 lines

  1. #include <puppy.h>
  2. #include <pupmem.h>
  3. #include <ascii.h>
  4.  
  5. /*
  6.     Miserable Message Editor
  7.  
  8.     T. Jennings
  9.     Fido Software
  10.     164 Shipley
  11.     San Francisco CA 94107
  12.     (415)-764-1688
  13.  
  14.     (k) all rights reversed
  15. */
  16.  
  17. #define WIDOFF    (sizeof("99: "))    /* size of line number prompt */
  18.  
  19.  
  20. /* Enter and edit text. */
  21.  
  22. edit(ln)
  23. int ln;        /* first line to input at, */
  24. {
  25. int end;            /* maximum line # */
  26. int lastline;            /* last line number, for detecting when to display */
  27. char *cp,c;
  28. char rptchar;            /* repeat-last-char count */
  29. char *tp;            /* ptr to the text buffer itself */
  30. char word[SS * 2];        /* word[] must be at least 2X max line len */
  31. FLAG run;            /* 1 == keep inputting, etc */
  32.  
  33. int pw;                /* length of 'word' (index into word[]) */
  34. int tw;                /* length of 'tp' (index into text line) */
  35.  
  36.     end= pup.msgsize / width; /* maximum lines */
  37.     tp= &text[ln * width];    /* ptr to the text */
  38.     tw= 0;            /* length of current line */
  39.  
  40.     lastline= -1;        /* trigger line # display */
  41.     rptchar= 0;        /* no character repeat count */
  42.     ins_line(ln,end);    /* incase we're I)nserting */
  43.  
  44.     run= 1;
  45.     while ( run && (ln < end)) {
  46.         if (ln != lastline) {
  47.             lastline= ln;            /* only once each line */
  48.             line= 0;            /* override "More?" */
  49.             mconout(CR); mconout(LF);    /* prevent autowrap */
  50.             mprintf("%2u: ",ln + 1);    /* display line number */
  51.             for (cp= tp; *cp; ++cp) {    /* display line so far */
  52.                 if (*cp >= ' ') mconout(*cp);
  53.             }
  54.         }
  55.  
  56. /* OK, now build a 'word', character by character. We stop (unbeknownst
  57. to the user) when we get a CR, space, etc. We also "fall out" if the word
  58. becomes too long to fit on the screen; hence the "while strlen + pc < width". */
  59.  
  60.         pw= 0;
  61.         while (tw + pw + WIDOFF < width) {    /* while it fits the line ... */
  62.             if (rptchar != 0) {        /* if repeated character */
  63.                 --rptchar;        /* count one, */
  64.             } else c= mconin();        /* get one word */
  65.  
  66.             if ((c == SUB) || (c == VT) || (c == ETX)) {
  67.                 run= 0;            /* if ^Z, ^K or ^C */
  68.                 break;            /* stop editing */
  69.             }
  70.             if (c == CR) break;        /* stop if CR, */
  71.             if (c == DEL) c= BS;        /* DEL becomes BS */
  72.  
  73.             if (c == TAB) {            /* if we get a tab, */
  74.                 rptchar= 8 - ((tw + pw) % 8); /* count = column mod 8 */
  75.                 c= ' ';            /* set the character, */
  76.                 continue;        /* then go do it */
  77.             }
  78.             if (c == CAN) {            /* if delete line */
  79.                 rptchar= tw + pw;    /* for the entire line, */
  80.                 c= BS;            /* set as back space, */
  81.                 continue;        /* go do it */
  82.             }
  83.  
  84. /* If a character delete, backspace on the screen. First delete characters 
  85. from the word we are building, if that is empty, then from the line we
  86. are building. */
  87.  
  88.             if (c == BS) {
  89.                 if (pw > 0) --pw;    /* remove chars from the word, */
  90.                 else if (tw > 0) --tw;     /* or the line, */
  91.                 else continue;        /* (neither, ignore BS) */
  92.                 erase(1);         /* then erase on screen */
  93.                 mconout(BS);
  94.                 continue;
  95.             }
  96.  
  97.             if (c >= ' ') {
  98.                 mconout(c);
  99.                 word[pw++]= c;        /* store chars in word */
  100.             }
  101.             if (pw >= sizeof(word) - 1) break; /* max length */
  102.             if (c == TAB) break;        /* word terminators */
  103.             if (c == ' ') break;
  104.             if (c == ',') break;
  105.             if (c == ';') break;
  106.         }
  107.         word[pw]= NUL;                /* terminate the word */
  108.         tp[tw]= NUL;                /* and the line so far */
  109.  
  110. /* We have text on the screen, and a word in the word[] array. If it will
  111. fit within the screen line length, display as-is, if not, do a CR/LF and
  112. do it on the next line. (This gets executed when word[] is zero length, 
  113. ie. only a CR is entered.) */
  114.  
  115.         if (tw + pw + WIDOFF < width) {
  116.             strcat(tp,word);        /* add it if it fits, */
  117.             tw += pw;            /* current line length, */
  118.  
  119. /* When we go to the next line, insert a blank line; if we're entering
  120. new text this is a waste of time, but if we're inserting it moves existing
  121. text down one line. */
  122.  
  123.         } else {                /* doesnt fit */
  124.             erase(pw);            /* clear last word from screen, */
  125.             if (tw == 0) strcat(tp," ");    /* no 0 length lines */
  126.             tp += width;            /* go to next line */
  127.             ++ln;                /* next line # */
  128.             ins_line(ln,end);        /* insert a blank one, */
  129.             strcpy(tp,word);        /* put word on next line, */
  130.             tw= pw;                /* also its line length */
  131.         }
  132.  
  133. /* If a CR was entered, then we want to force things to start on the next 
  134. line. Also stuff a CR when the line is ended if its not a blank line by itself. */
  135.  
  136.         if (c == CR) {                /* if hard return */
  137.             strcat(tp,"\r\n");        /* add a CR/LF */
  138.             tp += width;            /* next line */
  139.             ++ln;                /* next line # */
  140.             ins_line(ln,end);        /* insert a blank one, */
  141.             tw= 0;                /* new line is blank */
  142.         }
  143.     }
  144.     if ( ! *tp) strcpy(tp,"\r\n");
  145.  
  146. /* Now find the first unused line, and return that as the next line. */
  147.  
  148.     while (*tp) {                    /* find next blank line */
  149.         if (ln >= end) break;            /* dont go past the end */
  150.         tp += width;
  151.         ++ln;
  152.     }
  153.     return(ln);
  154. }
  155.  
  156. /* Delete a line from the text array. */
  157.  
  158. del_line(line,end)
  159. int line,end;
  160. {
  161. char *tp;
  162.  
  163.     tp= &text[line * width];            /* ptr to 1st line */
  164.     while (line < end) {
  165.         strcpy(tp,tp + width);            /* copy the line, */
  166.         tp += width;                /* next ... */
  167.         ++line;
  168.     }
  169.     *tp= NUL;                    /* last line is empty */
  170.     return(--end);
  171. }
  172.  
  173. /* Insert a blank line. Copies all lines down one, dropping
  174. off one at the bottom (which is presumably blank.) */
  175.  
  176. ins_line(line,end)
  177. int line,end;
  178. {
  179. char *tp;
  180. int i;
  181.  
  182.     tp= &text[end * width];            /* tp == address of last line, */
  183.     for (i= end - line; i; --i) {
  184.         strcpy(tp,tp - width);        /* copy line down, */
  185.         tp -= width;            /* next ... */
  186.     }
  187.     *tp= NUL;                /* inserted line is empty */
  188.     return(end);
  189. }
  190.  
  191. /* Erase a word. Backspace, then type spaces. */
  192.  
  193. erase(n)
  194. int n;
  195. {
  196. int i;
  197.  
  198.     for (i= 0; i < n; i++) mconout(BS);
  199.     for (i= 0; i < n; i++) mconout(' ');
  200. }
  201.